package edu.hawaii.myisern.action;

import java.io.IOException;
import javax.xml.bind.JAXBException;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationError;
import edu.hawaii.myisern.model.MyIsernModel;
import edu.hawaii.myisern.organizations.jaxb.AffiliatedResearchers;
import edu.hawaii.myisern.organizations.jaxb.Organization;
import edu.hawaii.myisern.organizations.jaxb.ResearchKeywords;

/**
 * Handles the adding of a new organization.
 * 
 * @author Sonwright M. Gomez
 * 
 */
public class AddOrganizationActionBean extends MyIsernActionBean {

  /** The singleton MyIsernModel. */
  private MyIsernModel myIsern = MyIsernModel.getInstance();

  /** Private fields needed for Organization fields */
  @Validate(required = true)
  private String organizationName;
  private String organizationType;
  private String organizationContact;
  private String organizationAffiliatedResearchers;
  private String organizationCountry;
  private String organizationResearchKeywords;
  private String organizationResearchDescription;
  private String organizationUrl;
  /** An error string, always displayed, but invisible if empty. */
  private String errorMessage = "";
  
  /**
   * Returns the error message, which may be empty.
   * 
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }
  
  /**
   * Set's the error message for the user.
   * 
   * @param errorMessage The error message. 
   */
  public void setErrorMessage(String errorMessage) {
    this.errorMessage = errorMessage;
  }
  
  /**
   * Set's the organization name.
   * 
   * @param oName the name of the organization.
   */
  public void setOrganizationName(String oName) {
    this.organizationName = oName;
  }

  /**
   * Get's the organization name.
   * 
   * @return organizationName The organization name
   */
  public String getOrganizationName() {
    return organizationName;
  }

  /**
   * Set's the organization name.
   * 
   * @param oType the name of the organization.
   */
  public void setOrganizationType(String oType) {
    this.organizationType = oType;
  }

  /**
   * Get's the organization type.
   * 
   * @return organizationType The organization type.
   */
  public String getOrganizationType() {
    return organizationType;
  }

  /**
   * Set's the organization contact.
   * 
   * @param oContact the name of the organization.
   */
  public void setOrganizationContact(String oContact) {
    this.organizationContact = oContact;
  }

  /**
   * Get's the organization type.
   * 
   * @return organizationContact The organization type.
   */
  public String getOrganizationContact() {
    return organizationContact;
  }

  /**
   * Set's the affiliated Researchers of the organization.
   * 
   * @param oAffiliatedResearchers the name of the organization.
   */
  public void setOrganizationAffiliatedResearchers(String oAffiliatedResearchers) {
    this.organizationAffiliatedResearchers = oAffiliatedResearchers;
  }

  /**
   * Get's the the affiliated researchers of the organization.
   * 
   * @return organizationAffiliatedResearchers The affiliated Researchers involved with the
   * Organization.
   */
  public String getOrganizationAffiliatedResearchers() {
    return organizationAffiliatedResearchers;
  }

  /**
   * Set's country of the organization.
   * 
   * @param oCountry the name of the organization.
   */
  public void setOrganizationCountry(String oCountry) {
    this.organizationCountry = oCountry;
  }

  /**
   * Get's the the country of the organization.
   * 
   * @return organizationCountry The country of Organization
   */
  public String getOrganizationCountry() {
    return organizationCountry;
  }

  /**
   * Set's Research keywords for the organization.
   * 
   * @param oResearchKeywords the name of the organization.
   */
  public void setOrganizationResearchKeywords(String oResearchKeywords) {
    this.organizationResearchKeywords = oResearchKeywords;
  }

  /**
   * Get's the the research keywords of the organization.
   * 
   * @return organizationResearchKeywords The keywords for Organization
   */
  public String getOrganizationResearchKeywords() {
    return organizationResearchKeywords;
  }

  /**
   * Set's organiztion Research description of the organization.
   * 
   * @param oResearchDescription the research description of the organization.
   */
  public void setOrganizationResearchDescription(String oResearchDescription) {
    this.organizationResearchDescription = oResearchDescription;
  }

  /**
   * Get's the the organization's Research Description
   * 
   * @return organizationResearchDescription The Research Description of the Organization.
   */
  public String getOrganizationResearchDescription() {
    return organizationResearchDescription;
  }

  /**
   * Set's url link of the organization.
   * 
   * @param oUrl the webpage of the organization.
   */
  public void setOrganizationUrl(String oUrl) {
    this.organizationUrl = oUrl;
  }

  /**
   * Get's the the url weblink of the organization.
   * 
   * @return organizationUrl The url of the Organization
   */
  public String getOrganizationUrl() {
    return organizationUrl;
  }

  /**
   * The handler for adding a new organization
   * 
   * @return the Resolution indicating to display mainMenu.jsp
   * @throws JAXBException if a JAXB error is encountered.
   * @throws IOException if an IO exception is encountered.
   */
  public Resolution submitAndSave() throws JAXBException, IOException {
    String delim = "," + "\\s";
    if (getOrganizationName().isEmpty()) {
      ValidationError error = new SimpleError("Requires an Organization Name");
      getContext().getValidationErrors().add("organizationName", error);
      return getContext().getSourcePageResolution();
    }
    else {
      // make sure it doesn't exist already
      if (myIsern.containsResearcher(this.organizationName)) {
        setErrorMessage("There is already an Organization with that name found "
            + "in the database.");
        return new ForwardResolution("/addOrganization.jsp");
      }
      else {
        // Add new Organization
        Organization newO = new Organization();

        // Add name of organization
        newO.setName(this.organizationName);

        // add type
        try {
          newO.setType(this.organizationType);
        }
        catch (NullPointerException e) {
          newO.setType("");
        }

        // add contact
        try {
          newO.setContact(this.organizationContact);
        }
        catch (NullPointerException e) {
          newO.setContact("");
        }

        // add affiliated researchers
        AffiliatedResearchers newAr = new AffiliatedResearchers();
        try {
          String[] tempAffilR = this.organizationAffiliatedResearchers.split(delim);
          for (String curr : tempAffilR) {
            newAr.getAffiliatedResearcher().add(curr.trim());
          }
        }
        catch (NullPointerException e) {
          newAr.getAffiliatedResearcher().add("");
        }
        newO.setAffiliatedResearchers(newAr);

        // add country
        try {
          newO.setCountry(this.organizationCountry);
        }
        catch (NullPointerException e) {
          newO.setCountry("");
        }

        // add research keywords
        ResearchKeywords newRk = new ResearchKeywords();
        try {
          String[] tempKeywords = this.organizationResearchKeywords.split(delim);
          for (String curr : tempKeywords) {
            newRk.getResearchKeyword().add(curr.trim());
          }
        }
        catch (NullPointerException e) {
          newRk.getResearchKeyword().add("");
        }
        newO.setResearchKeywords(newRk);

        // add research description
        try {
          newO.setResearchDescription(this.organizationResearchDescription);
        }
        catch (NullPointerException e) {
          newO.setResearchDescription("");
        }
        // add url
        try {
          newO.setHomePage(this.organizationUrl);
        }
        catch (NullPointerException e) {
          newO.setHomePage("");
        }
        // save's the new organization

        myIsern.addOrganization(newO);
        myIsern.saveOrganizations();

        return new ForwardResolution("/mainMenu.jsp");
      }
    }
  }

  /**
   * Goes back to the main menu without saving anything.
   * 
   * @return Resultion that displays the mainMenu.jsp page.
   */
  @DontValidate
  public Resolution cancel() {
    return new ForwardResolution("/mainMenu.jsp");
  }

}
